package cloud.xiangyixiang.www.spring.boot.java.basics.controller;

/**
 * <p>
 * JAVA String 字符串
 * </p>
 *
 * @author zhixinglu
 * @date 2023/9/2 17:05
 */
public class StringClassController {

    public static void main(String[] args) {

        description();

        // 效率测试
        //test1();

        //test2();

        //test3();

        //test4();

        test5();



    }

    public static void description(){

        System.out.println("String、StringBuilder和StringBuffer");
        System.out.println("1.主要区别: ");
        System.out.println("    * String是不可变字符序列，StringBuilder和StringBuffer是可变字符序列。");
        System.out.println("    * 执行速度StringBuilder > StringBuffer > String。");
        System.out.println("    * StringBuilder是非线程安全的，StringBuffer是线程安全的。");


        System.out.println();

    }

    /**
     * + 符号实现
     */
    public static void test1(){
        System.out.println("+ 符号实现： ====================");
        int a = 10;
        String b = "知行录";
        System.out.println("eg1: int a = 10; String b = \"哪吒\";");
        System.out.println("     + 拼接 result：" + a + b);

        byte byte0 = 10;
        String c = "知行录";
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder stringBuilderAppend = stringBuilder.append(c).append(byte0);
        System.out.println("eg2: byte byte0 = 10; String c = \"知行录\";");
        System.out.println("     StringBuilder.append() 结果: " + stringBuilderAppend);

        System.out.println();

    }

    /**
     * 效率测试 + 拼接
     *
     * 10万条time: 8684ms 8602ms 8403ms
     */
    public static void test2() {
        String str = "知行录,";
        String ret = "";
        System.out.println("+字符串拼接开始...");
        long start = System.currentTimeMillis();
        // + 在循环中的效率太低，用10万条测试吧
        for (int i = 0; i < 100000; i++) {
            ret += str;
        }
        long end = System.currentTimeMillis();
        System.out.println("效率测试：+号拼接10万条数据耗时：" + (end - start) + "ms");
        System.out.println("************");

        System.out.println();
    }

    /**
     * 效率测试 StringBuilder 拼接
     *
     * 10万条time: 14ms 10ms 11ms
     * 100万条time: 29ms 25ms 26ms
     * 1000万条time: 152ms 155ms 156ms
     */
    public static void test3() {
        String str = "知行录,";
        StringBuilder builder = new StringBuilder();
        System.out.println("StringBuilder, 字符串拼接开始...");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            builder.append(str);
        }
        long end = System.currentTimeMillis();
        //168ms, 173ms, 239ms
        System.out.println("效率测试：StringBuilder拼接1000万条数据耗时："+(end-start)+"ms");
        System.out.println("************");

        System.out.println();
    }

    /**
     * 效率测试 StringBuffer 拼接
     *
     * 10万条time: 10ms 10ms 11ms
     * 100万条time: 33ms 33ms 33ms
     * 1000万条time: 238ms 242ms 236ms
     */
    public static void test4() {
        String str = "知行录,";
        StringBuffer buffer = new StringBuffer();
        System.out.println("StringBuffer,字符串拼接开始...");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
            buffer.append(str);
        }
        long end = System.currentTimeMillis();
        //527ms, 343ms, 398ms
        System.out.println("效率测试：StringBuffer拼接 1000万条数据耗时："+(end-start)+"ms");
        System.out.println("************");

        System.out.println();
    }

    public static void test5(){
        // 1. 新建一个引用s1指向堆中的对象s1,值为"linkunknown知行录"
        String s1 = new String("linkunknown") + new String("知行录");
        // 2. 新建一个引用s2指向堆中的对象s2,值为"linkunknown知行录"
        String s2 = new String("link") + new String("unknown知行录");
        // 3. 执行s1.intern()会在字符串常量池中新建一个引用"linkunknown知行录"，该引用指向s1在堆中的地址，并新建一个引用s3指向字符串常量池中的"linkunknown知行录"
        String s3 = s1.intern();
        // 4. 执行s2.intern()不会在字符串常量池中创建新的引用，因为"linkunknown知行录"已存在，因此只执行了新建一个引用s4指向字符串常量池中"linkunknown知行录"的操作
        String s4 = s2.intern();
        // s3和s4指向的都是字符串常量池中的"linkunknown知行录"，而这个"linkunknown知行录"都指向堆中s1的地址
        // true
        System.out.println(s1 == s3);
        // true
        System.out.println(s1 == s4);
        // s3和s4最终关联堆中的地址是对象s1
        // false
        System.out.println(s2 == s3);
        // false
        System.out.println(s2 == s4);
    }

}
